home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / da-explor.c < prev    next >
Text File  |  1985-11-25  |  13KB  |  506 lines

  1. /*
  2. Here is the explorer desk accessory that comes with the Manx Aztec C
  3. system.  It is written by superprogrammer Jim Goodnow (who reportedly
  4. produces bug-free C code faster than lex or yacc).  Explorer is public
  5. domain (sort of -- you can give it away but not sell it).  It is the
  6. first desk accessory we've heard of written entirely in C (almost --
  7. there are a few lines of assembly at the beginning).  
  8.  
  9. Explorer let's you browse through memory while an application is
  10. running looking at memory as hex or as strings.  The box at the top of
  11. the explorer window lets you specify a start address for the display
  12. (this is more convenient than scrolling through the half megabyte
  13. address space on a Fat Mac).
  14.  
  15. First suggested use: cheating at Zork.  If you look through Zork with
  16. fedit you'll find that Zork encrypts its strings on the disk.  But who
  17. knows what you'll find when you look through RAM?  It must decrypt them
  18. sometime before displaying them.  (If you look through the CP/M version
  19. of WordStar with something like fedit, you'll find the message "Nosey,
  20. aren't you?")
  21.  
  22. Manx says they are working on a source level C debugger.  They were
  23. going to devote their efforts to a resource editor instead, but they
  24. decided they liked Apple's, licensed it, and stopped working on their
  25. own.  I've been using Aztec C on our Hyperdrive Mac.  There are some
  26. problems but overall I think it's still the best Mac development system
  27. available (except for cost which is where Sumacc wins) and has the
  28. fastest time from edit to run (compiles about as fast as Sumacc on a
  29. normally loaded Vax and has no downloading; also supports overlays and
  30. stdio).  Text scrolling is much faster than it was in the beta release.
  31. I used the beta release to compile the Mac version of xlisp that is
  32. floating around.  Maybe it's time to find the latest xlisp sources and
  33. use this lates Manx compiler to compiler them.
  34.  
  35. So here is explor.c (the Manx C source of the explorer desk accessory)
  36. and explor.hex (the binhex encoded version of the compiled explor 
  37. desk accessory).  
  38.  
  39. Dan. (winkler@harvard)
  40.  
  41.  *
  42.  *              Explorer - Version 1.0
  43.  *
  44.  *          A Desk Accessory for the Macintosh
  45.  *
  46.  *  Copyright (C) 1984 by Manx Software Systems, Inc.
  47.  *      May be used, but not sold without permission.
  48.  *
  49.  *  written by Jim Goodnow II, December 7-8, 1984
  50.  */
  51.  
  52. #asm
  53. main
  54.     dc.w    $2400           ;ctl-enable, need time
  55.     dc.w    5*60            ;update every 5 seconds
  56.     dc.w    $000a           ;detect mouse and key down events
  57.     dc.w    -777            ;menu ID number (must be negative)
  58.  
  59.     dc.w    open_-main      ;open routine
  60.     dc.w    nop_-main       ;prime routine
  61.     dc.w    control_-main   ;control routine
  62.     dc.w    nop_-main       ;status routine
  63.     dc.w    close_-main     ;close routine
  64.  
  65. title_
  66.     dc.b    8
  67.     dc.b    "Explorer"
  68.     ds      0               ;for alignment
  69.  
  70.     public  _Uend_,_Dorg_,_Cend_
  71.  
  72. save_
  73.     lea     main+(_Uend_-_Dorg_)+(_Cend_-main),a4       ;set up globals
  74.     move.l  a0,Pbp_                                     ;save pb pointer
  75.     move.l  a1,Dp_                                      ;save DCE pointer
  76.     rts
  77.  
  78. restore_
  79.     move.l  Pbp_,a0
  80.     rts
  81. #endasm
  82.  
  83. #define _DRIVER
  84. #define SMALL_MEM
  85. #include    <quickdraw.h>
  86. #include    <toolutil.h>
  87. #include    <window.h>
  88. #include    <memory.h>
  89. #include    <osutil.h>
  90. #include    <menu.h>
  91. #include    <control.h>
  92. #undef SMALL_MEM
  93. #include    <event.h>
  94. #include    <textedit.h>
  95. #include    <pb.h>
  96. #include    <desk.h>
  97.  
  98. #define TRUE    0x100
  99. #define FALSE   0x000
  100.  
  101. #define NLINES  16                  /* number of lines in window    */
  102. #define MENUID  -777                /* must be negative             */
  103. #define MEMTOP  (*(long *)0x108)    /* top of memory 128 or 512K    */
  104. #define SP      (*(struct storage **)Dp->dCtlStorage)
  105.  
  106. DCEPtr Dp;
  107. ParmBlkPtr Pbp;
  108.  
  109. Rect Wind_rect = {100, 150, 275, 360};
  110. Rect Scrl_rect = {-1, 194, 176, 211};
  111. Rect Cont_rect = {0, 0, 176, 194};
  112. Rect Full_rect = {0, 0, 176, 211};
  113. Rect Edit_rect = {-1, 44, 12, 90};
  114.  
  115. Cursor Ibeam = {
  116. 0x3838, 0x3C78, 0x0280, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
  117. 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0280, 0x3C78, 0x3838,
  118. 0x3838, 0x3C78, 0x0280, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
  119. 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0280, 0x3C78, 0x3838,
  120. 0x0008, 0x0008 };
  121.  
  122. struct storage {
  123.     MenuHandle      menu;
  124.     ControlHandle   vscrl;
  125.     char *          where;
  126.     short           autoupdate;
  127.     short           size;
  128.     short           incr;
  129.     TEHandle        hte;
  130. };
  131.  
  132. open()
  133. {
  134.     register WindowPtr wp;
  135.     register struct DCE *dp;
  136.     register struct storage *sp;
  137.     extern char title[];
  138.     struct windowpeek {
  139.         GrafPort    port;
  140.         int         windowKind;
  141.     };
  142.  
  143.     save();
  144.     dp = Dp;
  145.     if (dp->dCtlWindow == 0) {
  146.         HLock(dp->dCtlStorage = NewHandle((long)sizeof(struct storage)));
  147.         sp = SP;
  148.         dp->dCtlWindow =
  149.         wp = NewWindow(0L, &Wind_rect, title, TRUE, noGrowDocProc, -1L, TRUE, 0L);
  150.         ((struct windowpeek *)wp)->windowKind = dp->dCtlRefNum;
  151.         sp->vscrl = NewControl(wp, &Scrl_rect, "", FALSE, 0, 0, 0x7fff, scrollBarProc, 0L);
  152.         sp->hte = 0;
  153.         sp->where = 0;
  154.         sp->size = 0;
  155.         sp->autoupdate = 0;
  156.         sp->incr = MEMTOP / 0x8000L;
  157.         sp->menu = NewMenu(MENUID, "\PExplorer");
  158.         AppendMenu(sp->menu,
  159.             "\PAuto-Refresh;Hand-Refresh;(-;Hexadecimal!\x12;Ascii");
  160.         HUnlock(dp->dCtlStorage);
  161.     }
  162.     restore();
  163.     return(0);
  164. }
  165.  
  166. close()
  167. {
  168.     register struct DCE *dp;
  169.  
  170.     save();
  171.     dp = Dp;
  172.     TEDispose(SP->hte);
  173.     DisposeWindow(dp->dCtlWindow);
  174.     dp->dCtlWindow = 0;
  175.     DeleteMenu(MENUID);
  176.     DrawMenuBar();
  177.     DisposHandle(SP->menu);
  178.     DisposHandle(dp->dCtlStorage);
  179.     restore();
  180.     return(0);
  181. }
  182.  
  183. nop()
  184. {
  185.     return(0);
  186. }
  187.  
  188. control()
  189. {
  190.     register struct storage *sp;
  191.     Point pt;
  192.     register int item;
  193.  
  194.     save();
  195.     HLock(Dp->dCtlStorage);
  196.     sp = SP;
  197.     SetPort(Dp->dCtlWindow);
  198.     switch(Pbp->u.cp.csCode) {
  199.     case accEvent:
  200.         doevent(sp, *(EventRecord **)&Pbp->u.cp.csParam);
  201.         break;
  202.     case accRun:
  203.         if (sp->autoupdate)
  204.             draw_wind();
  205.         break;
  206.     case accCursor:
  207.         if (sp->hte)
  208.             TEIdle(sp->hte);
  209.         GetMouse(&pt);
  210.         if (PtInRect(pass(pt), &Edit_rect) & TRUE)
  211.             SetCursor(&Ibeam);
  212.         else
  213.             InitCursor();
  214.         break;
  215.     case accMenu:
  216.         switch(item = ((int *)&Pbp->u.cp.csParam)[1]) {
  217.         case 1:                             /* auto refresh     */
  218.             sp->autoupdate ^= TRUE;
  219.             CheckItem(sp->menu, 1, sp->autoupdate);
  220.             break;
  221.         case 2:                             /* manual refresh   */
  222.             draw_wind();
  223.             break;
  224.         case 4:
  225.         case 5:
  226.             sp->size = item==4?8:16;
  227.             CheckItem(sp->menu, 4, item==4?TRUE:FALSE);
  228.             CheckItem(sp->menu, 5, item==5?TRUE:FALSE);
  229.             EraseRect(&Cont_rect);
  230.             draw_wind();
  231.             break;
  232.         }
  233.         break;
  234.     case accUndo:
  235.         break;
  236.     case accCut:
  237.         TECut(sp->hte);
  238.         break;
  239.     case accCopy:
  240.         TECopy(sp->hte);
  241.         break;
  242.     case accPaste:
  243.         TEPaste(sp->hte);
  244.         break;
  245.     case accClear:
  246.         TEDelete(sp->hte);
  247.         break;
  248.     }
  249.     HUnlock(Dp->dCtlStorage);
  250.     restore();
  251.     return(0);
  252. }
  253.  
  254. doevent(sp, ep)
  255. register struct storage *sp;
  256. register EventRecord *ep;
  257. {
  258.     register int c;
  259.     register long l;
  260.     ControlHandle chdl;
  261.     pascal void scrlup(), scrldn();
  262.     long xtol();
  263.  
  264.     switch(ep->what) {
  265.     case keyDown:
  266.         if ((ep->modifiers & (cmdKey | optionKey)) == 0) {
  267.             c = (char)ep->message;
  268.             if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == 8) {
  269.                 TEKey(c, sp->hte);
  270.                 break;
  271.             }
  272.             if ((c == '\r' || c == 3) && (l = xtol(sp->hte)) != -1) {
  273.                 sp->where = l;
  274.                 TESetSelect(0L, 1000L, sp->hte);
  275.                 draw_wind();
  276.                 break;
  277.             }
  278.         }
  279.         SysBeep(2);
  280.         break;
  281.     case mouseDown:
  282.         GlobalToLocal(&ep->where);
  283.         if (PtInRect(pass(ep->where), &Cont_rect)&TRUE) {
  284.             if (PtInRect(pass(ep->where), &Edit_rect) & TRUE)
  285.                 TEClick(pass(ep->where), ep->modifiers&shiftKey?TRUE:FALSE, sp->hte);
  286.         }
  287.         else {
  288.             c = FindControl(pass(ep->where), Dp->dCtlWindow, &chdl);
  289.             switch(c) {
  290.             case inUpButton:
  291.                 TrackControl(chdl, pass(ep->where), scrlup);
  292.                 break;
  293.             case inDownButton:
  294.                 TrackControl(chdl, pass(ep->where), scrldn);
  295.                 break;
  296.             case inPageUp:
  297.                 scrlpage(chdl, c, -NLINES);
  298.                 break;
  299.             case inPageDown:
  300.                 scrlpage(chdl, c, NLINES);
  301.                 break;
  302.             case inThumb:
  303.                 TrackControl(chdl, pass(ep->where), 0L);
  304.                 sp->where = (char *)((long)sp->incr * GetCtlValue(chdl));
  305.                 draw_wind();
  306.                 break;
  307.             }
  308.         }
  309.         break;
  310.     case activateEvt:
  311.         if (ep->modifiers&1) {
  312.             if (sp->size == 0) {
  313.                 signature();
  314.                 sp->size = 8;
  315.             }
  316.             InsertMenu(sp->menu, 0);
  317.             ShowControl(sp->vscrl);
  318.             TEActivate(sp->hte);
  319.         }
  320.         else {
  321.             DeleteMenu(MENUID);
  322.             HideControl(sp->vscrl);
  323.             TEDeactivate(sp->hte);
  324.         }
  325.         DrawMenuBar();
  326.         break;
  327.     case updateEvt:
  328.         BeginUpdate(ep->message);
  329.         draw_wind();
  330.         DrawControls(ep->message);
  331.         EndUpdate(ep->message);
  332.         break;
  333.     }
  334. }
  335.  
  336. signature()
  337. {
  338.     register WindowPtr wp;
  339.     register long tick;
  340.     Rect r;
  341.  
  342.     wp = Dp->dCtlWindow;
  343.     wp->txFont = 0;
  344.     wp->txSize = 0;
  345.     wp->txMode = srcCopy;
  346.     MoveTo(90, 20);
  347.     DrawString("\Pby");
  348.     MoveTo(50,40);
  349.     DrawString("\PJim Goodnow II");
  350.     MoveTo(55, 60);
  351.     DrawString("\Pusing Aztec C");
  352.     MoveTo(10, 90);
  353.     DrawString("\PManx ");
  354.     Move(0, 20);
  355.     DrawString("\PSoftware ");
  356.     Move(0, 20);
  357.     DrawString("\PSystems");
  358.     Move(0, 20);
  359.     DrawString("\PInc.");
  360.     for (tick=TickCount()+100;TickCount() < tick;)
  361.         ;
  362.     EraseRect(&wp->portRect);
  363.     wp->txFont = 4;
  364.     wp->txSize = 9;
  365.     r = Edit_rect;
  366.     InsetRect(&r, 4, 1);
  367.     SP->hte = TENew(&r, &r);
  368. }
  369.  
  370. draw_wind()
  371. {
  372.     register unsigned char *cp, *wp;
  373.     register unsigned long l;
  374.     register int k, i, j;
  375.     struct storage *sp;
  376.     char buf[40];
  377.     static char hex[] = "0123456789abcdef";
  378.  
  379.     sp = SP;
  380.     l = sp->where;
  381.     if (l < 0)
  382.         l = 0;
  383.     if (l > MEMTOP - sp->size*NLINES)
  384.         l = MEMTOP - sp->size * NLINES;
  385.     wp = sp->where = l;
  386.     SetCtlValue(sp->vscrl, (int)(l/sp->incr));
  387.     RectRgn(Dp->dCtlWindow->clipRgn, &Cont_rect);
  388.     MoveTo(4, 9);
  389.     DrawString("\PStart: ");
  390.     TEUpdate(&Edit_rect, sp->hte);
  391.     FrameRect(&Edit_rect);
  392.     for (i=0;i<NLINES;i++) {
  393.         k = i * sp->size;
  394.         MoveTo(4, i*10+24);
  395.         cp = buf;
  396.         l = wp + k;
  397.         for (j=5;j>=0;l>>=4)
  398.             cp[j--] = hex[l%16];
  399.         cp += 6;
  400.         *cp++ = ':';
  401.         if (sp->size == 8) {
  402.             for (j=0;j<8;j++) {
  403.                 *cp++ = ' ';
  404.                 *cp++ = hex[wp[k+j]/16];
  405.                 *cp++ = hex[wp[k+j]%16];
  406.             }
  407.         }
  408.         *cp = 0;
  409.         DrawString(ctop(buf));
  410.         if (sp->size == 16) {
  411.             cp = buf;
  412.             *cp++ = 17;
  413.             *cp++ = ' ';
  414.             for (j=0;j<16;j++) {
  415.                 if (wp[k+j] > 0x1f && wp[k+j] < 0x80)
  416.                     *cp++ = wp[k+j];
  417.                 else
  418.                     *cp++ = '.';
  419.             }
  420.             DrawString(buf);
  421.         }
  422.     }
  423.     RectRgn(Dp->dCtlWindow->clipRgn, &Full_rect);
  424. }
  425.  
  426. pascal void
  427. scrlup(chdl, code)
  428. ControlHandle chdl;
  429. int code;
  430. {
  431.     scroll(chdl, code, inUpButton);
  432. }
  433.  
  434. pascal void
  435. scrldn(chdl, code)
  436. ControlHandle chdl;
  437. int code;
  438. {
  439.     scroll(chdl, code, inDownButton);
  440. }
  441.  
  442. scroll(chdl, code, where)
  443. ControlHandle chdl;
  444. {
  445.     register struct storage *sp;
  446.  
  447. #asm
  448.     move.l  a4,-(sp)
  449.     lea     main+(_Uend_-_Dorg_)+(_Cend_-main),a4       ;set up globals
  450. #endasm
  451.     if (code == where) {
  452.         sp = SP;
  453.         if (where == inUpButton)
  454.             sp->where -= sp->size;
  455.         else
  456.             sp->where += sp->size;
  457.         draw_wind();
  458.     }
  459.     ;
  460. #asm
  461.     move.l  (sp)+,a4
  462. #endasm
  463. }
  464.  
  465. scrlpage(chdl, code, amount)
  466. ControlHandle chdl;
  467. {
  468.     Point pt;
  469.     struct storage *sp;
  470.  
  471.     sp = SP;
  472.     do {
  473.         GetMouse(&pt);
  474.         if (TestControl(chdl, pass(pt)) == code) {
  475.             sp->where += sp->size*amount;
  476.             draw_wind();
  477.         }
  478.     } while (StillDown()&TRUE);
  479. }
  480.  
  481. long
  482. xtol(hte)
  483. TEHandle hte;
  484. {
  485.     register char *cp;
  486.     register long i = 0, l = 0;
  487.     register int c, n;
  488.  
  489.     n = (*hte)->length;
  490.     cp = *(*hte)->hText;
  491.     while (n--) {
  492.         c = *cp++;
  493.         if (c >= 'a' && c <= 'f')
  494.             c -= 'a' - 10;
  495.         else if (c >= '0' && c <= '9')
  496.             c -= '0';
  497.         else {
  498.             TESetSelect(i, i+1, hte);
  499.             return(-1);
  500.         }
  501.         l = l * 16 + c;
  502.         i++;
  503.     }
  504.     return(l);
  505. }
  506.